<script setup lang="ts">
import Stub from './components/Stub.vue'
import Panel from './components/Panel.vue'
import Console from './components/Console.vue'
import { Command, Device, Id, Message, MessageType, Task, Time, Trainee } from './model'
import { onMounted, reactive, ref } from 'vue'
import * as api from './api'
import { Delete, Download, QuestionFilled, User } from '@element-plus/icons-vue'

const title = import.meta.env.VITE_TITLE

const availableCommands = reactive<Readonly<Command>[]>([])
const tasks = reactive<Task[]>([])
const messages = reactive<Message[]>([])

const socket = new WebSocket(import.meta.env.VITE_WSHOST)
socket.addEventListener('message', ({ data }) => {
  const { type = MessageType.Receive, time, body = '' } = data as {
    type: number
    time: number
    body?: string
  }
  const msg = new Message(type, Time.fromPrimary(time), body)
  messages.push(msg)
})

const bindingDialogVisible = ref(false)
const devices = reactive<Readonly<Device>[]>([])
const trainees = reactive<Readonly<Trainee>[]>([])

if (import.meta.env.MODE === 'mock') {
  setTimeout(() => {
    messages.push(new Message(
      MessageType.Receive,
      Time.fromPrimary(2),
    ), new Message(
      MessageType.Error,
      Time.fromPrimary(3),
      '无响应',
    ), new Message(
      MessageType.Command,
      Time.fromPrimary(4),
    ))
  }, 30)
}

onMounted(async () => {
  const commands = await api.getAllCommands()
  availableCommands.push(...commands)
  const deviceList = await api.getAllDevices()
  devices.push(...deviceList)
  const traineeList = await api.getAllTrainees()
  trainees.push(...traineeList)
})

function addTask(taskId: Id) {
  const task = new Task(taskId, tasks.at(-1)?.time ?? new Time())
  tasks.push(task)
}

function updateCommand(index: number, id: Id) {
  tasks[index].id = id
}

function updateTime(index: number, time: Time) {
  tasks[index].time = time
}

function deleteTask(index: number) {
  tasks.splice(index, 1)
}

function sendBatch(tasks: readonly Readonly<Task>[]) {
  api.sendBatch(tasks)
}

function downloadText(content: string, filename: string) {
  const blob = new Blob([content], { type: 'text/plain' })
  const a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = filename
  a.click()
}

function toText(messages: readonly Readonly<Message>[]) {
  return messages.map(msg => msg.toText()).join('\n')
}
</script>

<template>
  <header>
    <h1 class="title">
      {{ title }}
    </h1>
  </header>

  <div class="box">
    <Stub
      class="stub"
      :commands="availableCommands"
      @add="addTask"
    >
      <template #header>
        <h3 class="sub-header util-header">
          可用命令
          <el-tooltip content="点击下列命令以添加任务">
            <el-icon>
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </h3>
      </template>
    </Stub>
    <Panel
      class="panel"
      :commands="availableCommands"
      :tasks="tasks"
      @update:command="updateCommand"
      @update:time="updateTime"
      @delete="deleteTask"
    >
      <template #header>
        <h3 class="sub-header util-header">
          <span>任务队列</span>
          <el-button type="primary" @click="sendBatch(tasks)">执行</el-button>
        </h3>
      </template>
    </Panel>
    <Console class="console" :messages="messages">
      <template #header>
        <h3 class="sub-header util-header">
          <div>
            信息输出
            <el-tooltip content="绑定人员">
              <el-button
                @click="bindingDialogVisible=true"
                type="primary"
                :icon="User"
              />
            </el-tooltip>
          </div>

          <el-button-group class="ml-4">
            <el-tooltip content="清空">
              <el-button
                type="primary"
                :icon="Delete"
                @click="messages.splice(0, messages.length)"
              />
            </el-tooltip>
            <el-tooltip content="下载">
              <el-button
                type="primary"
                :icon="Download"
                @click="downloadText(toText(messages),`log-${Date.now()}.txt`)"
              />
            </el-tooltip>
          </el-button-group>
        </h3>
      </template>
    </Console>
  </div>

  <el-dialog
    v-model="bindingDialogVisible"
    title="绑定人员"
    width="600"
  >
    <ul>
      <li
        v-for="device in devices"
        :key="device.id"
      >
        <el-select>
          <el-option
            v-for="trainee in trainees"
            :key="trainee.id"
          >
            {{ trainee.name }}
          </el-option>
        </el-select>
      </li>
    </ul>
  </el-dialog>
</template>

<style scoped>
.title {
  padding-left: 1em;
  line-height: 2;
  text-align: center;
  font-size: 32px;
  background-color: #cdecf6;
}

.box {
  display: flex;
}

.stub,
.panel,
.console {
  padding: 20px;
  max-height: 100vh;
  overflow-y: auto;
}

.stub {
  width: 300px;
}

.panel {
  width: 500px;
  background-color: #f5f5f5;
}

.console {
  flex: 1;
}

.sub-header {
  padding-bottom: 10px;
  border-bottom: 1px solid #999;
}

.util-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
